﻿using System;
using System.Collections.Generic;
using System.Linq;
using Castle.MicroKernel;
using Castle.MicroKernel.Handlers;
using Castle.Windsor;
using NUnit.Framework;

namespace WindsorInitConfig {
    // doesn't compile due to breaking changes in Windsor 3.x
    //[TestFixture]
    //public class ResolveAllThrowing {
    //    [Test]
    //    [ExpectedException(typeof (Exception))]
    //    public void WaitingThrows() {
    //        var container = new WindsorContainer();
    //        container.AddComponent<ISomething, Something>();
    //        container.ResolveAllWithThrow<ISomething>();
    //    }

    //    [Test]
    //    public void NotWaitingResolves() {
    //        var container = new WindsorContainer();
    //        container.AddComponent<ISomething, Something>();
    //        container.AddComponent<SomethingElse>();
    //        var all = container.ResolveAllWithThrow<ISomething>();
    //        Assert.AreEqual(1, all.Length);
    //        container.ResolveAllWithThrow<ISomething>();
    //        container.ResolveAllWithThrow<ISomething>();
    //    }

    //    public interface ISomething {}

    //    public class Something : ISomething {
    //        public Something(SomethingElse e) {}
    //    }

    //    public class SomethingElse {}
    //}

    //public static class WindsorResolveExtensions {
    //    public static T[] ResolveAllWithThrow<T>(this IWindsorContainer container) {
    //        return ResolveAllWithThrow(container, typeof (T)).Cast<T>().ToArray();
    //    }

    //    /// <summary>
    //    /// Based on the original ResolveAll()
    //    /// </summary>
    //    /// <see cref="http://fisheye2.atlassian.com/browse/castleproject/InversionOfControl/trunk/src/Castle.MicroKernel/DefaultKernel_Resolve.cs?r=6175#l148"/>
    //    /// <param name="container"></param>
    //    /// <param name="service"></param>
    //    /// <returns></returns>
    //    public static object[] ResolveAllWithThrow(this IWindsorContainer container, Type service) {
    //        var resolved = new Dictionary<IHandler, object>();
    //        using (var kernel = new HelperKernel()) {
    //            container.Kernel.AddChildKernel(kernel);
    //            try {
    //                foreach (var handler in kernel.GetAssignableHandlers(service)) {
    //                    if (handler.CurrentState != HandlerState.Valid)
    //                        throw new Exception(string.Format("Component '{0}' has a waiting dependency", handler.ComponentModel.Name));

    //                    var actualHandler = handler;

    //                    if (handler is ForwardingHandler)
    //                        actualHandler = ((ForwardingHandler) handler).Target;

    //                    if (!resolved.ContainsKey(actualHandler)) {
    //                        var component = kernel.ResolveComponent(actualHandler);
    //                        resolved.Add(actualHandler, component);
    //                    }
    //                }
    //                return resolved.Select(kv => kv.Value).ToArray();
    //            } finally {
    //                container.Kernel.RemoveChildKernel(kernel);
    //            }
    //        }
    //    }

    //    private class HelperKernel : DefaultKernel {
    //        public new object ResolveComponent(IHandler h) {
    //            return base.ResolveComponent(h);
    //        }
    //    }
    //}
}